package practice_2025_9.practice_9_30;

class Solution {
    /**
     * 跳跃游戏
     * @param nums
     * @return
     */
    public boolean canJump(int[] nums) {
       // 判断能否到达最后一个下标
       // dp[i]: 当前位置是否可以到达
       int len = nums.length;
       boolean[] dp = new boolean[len];
       dp[0] = true;
       for(int i = 0; i < len; i++) {
            if (!dp[i]) {
                return false;
            }
            int count = nums[i];
            for(int j = 1; j <= count && (i + j) < len; j++) {
                dp[i + j] = true;
            }
       }
       return dp[len - 1];
    }

    /**
     * 跳跃游戏2
     * 贪心
     * @param nums
     * @return
     */
    public boolean canJump2(int[] nums) {
        int len = nums.length;
        if (len <= 1) {
            return true;
        }
        int left = 0, right = 0;
        while(left <= right) {
            // 更新 right
            int newRight = right;
            for(int i = left; i <= right; i++) {
                if (newRight < i + nums[i]) {
                    newRight = i + nums[i];
                }
            }
            left = right + 1;
            right = newRight;
            if (right >= len - 1) {
                return true;
            }
        }
        // System.out.println(right);
        return right >= (len - 1);
    }

    /**
     * 打家劫舍
     * @param nums
     * @return
     */
    public int rob(int[] nums) {
        // 不能偷相邻的两家
        // f[i]: 偷当前这家的最大金额
        // g[i]: 不偷当前这家的最大金额
        int len = nums.length;
        int[] f = new int[len];
        int[] g = new int[len];
        f[0] = nums[0];
        for(int i = 1; i < len; i++) {
            f[i] = Math.max(f[i - 1], g[i - 1] + nums[i]);
            g[i] = Math.max(g[i - 1], f[i - 1]);
        }
        return Math.max(g[len - 1], f[len - 1]);
    }
}